home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Ham Radio 2000 #2
/
Ham Radio 2000 - Volume 2.iso
/
HAMV2
/
ANTENNA
/
YAGIU112
/
OUTPUT.C
< prev
next >
Wrap
C/C++ Source or Header
|
1995-08-07
|
7KB
|
211 lines
/*
A few changes have been made, including:
1) Memory is freed, rather than lying on the OS
2) Memory is no longer repeatdly allocated, which meant excessive use
of system memory.
*/
#include <stdio.h>
#include <malloc.h>
#include <math.h>
#include <string.h>
#include <sys/types.h>
#include "yagi.h"
double Zo=Z0; /* Z0 is defined in yagi.h */
extern int optind, opterr;
extern char *optarg;
double min_offset_from_peak, angular_stepsize_2; /* not needed */
double pin, design_f, normalised_f, f;
double gain_E_plane, gain_H_plane, peak_gain;
struct element_data *coordinates;
struct FCOMPLEX *current;
int elements;
int main(int argc, char **argv)
{
FILE *ifp, *ofp, *gain_fp;
char *input_filename, *output_filename, *temp;
char *gain_filename;
double min_f, max_f, step_f, vswr, angular_step;
double magnitude, phase,max_SL,E_max=E_MAX, H_max=H_MAX;
struct FCOMPLEX *voltage, input_impedance;
double fb_ratio,gain_E_plane_back;
double gain_H_plane_back;
struct flags flag;
struct pattern pattern_shape;
double x;
int k=1, c;
input_filename=string(0L, 100L);
output_filename=string(0L, 100L);
gain_filename=string(0L, 100L);
memset((char *) &flag, 0, sizeof(flag));
while ((c = getoptions(argc,argv,"cehsE:H:Z:")) != -1)
switch (c)
{ case 'c':
flag.cflg=1;
break;
case 'e': /* suppress E- plane 3dB BW */
flag.eflg=1;
break;
case 'h': /* suppress H- plane 3dB BW */
flag.hflg=1;
break;
case 's': /* suppress diagnostics */
flag.sflg=1;
break;
case 'E': /* Max angle in E plane to look for -3dB */
E_max=atof(optarg);
break;
case 'H':
H_max=atof(optarg); /* max angle in H plane to look for -3dB */
break;
case 'Z': /* Zo */
Zo=atof(optarg);
break;
case '?': /* default */
flag.errflg=1;
break;
}
if((argc-optind != 1) || flag.errflg)
{
usage_output(argv[0]);
exit(0);
}
/* The file read by 'output' is expected to have a .out extension.
'output' creates files with extensions:
.dat Containing the basic broperties of impedance, gain etc as a function
of frequency.
.gai Contains field patterns (gain) in the both H and E plane.
We here get all the file names, then open files. */
strcpy(input_filename, argv[optind]);
strcpy(output_filename, *(argv+optind));
strcpy(gain_filename, *(argv+optind));
strcat(input_filename,".out");
strcat(output_filename,".dat");
strcat(gain_filename,".gai");
ifp=fopen(input_filename,"rb");
ofp=fopen(output_filename,"wb");
gain_fp=fopen(gain_filename,"wt");
if(ifp == NULL)
{
fprintf(stderr,"Cant open %s\n", input_filename);
exit(10);
}
temp=string(0L,100L);
/* No longer need to refer to files by names, we just use the
file pointers, so free memory associated with names. */
free_string(output_filename,0L,100L);
free_string(gain_filename,0L,100L);
/* Read the header on the .out file, which is usually 100 Bytes,
but can be defined in yagi.h as HEADER_SIZE */
elements=read_header(ifp, ofp, &min_f, &max_f, &step_f, &design_f, &angular_step);
/* Creatre an array of structures, so contain the x and y locations of
each element, and the lengths of the elements. All dimensions are in m */
coordinates=element_data_vector(1,elements); /* x,y &l of centre of ele's */
/* read into memory the x,y, and lengths of all elements */
fread((char *) &coordinates[1], sizeof(struct element_data),elements,ifp);
/* Create arrays to hold real and imaginary components of voltage */
voltage=FCOMPLEXvector(1,elements);
current=FCOMPLEXvector(1,elements);
/* read voltages applied to elements into memory */
fread((char *) &voltage[1], sizeof(struct FCOMPLEX),elements, ifp);
/* Now print a one line header to put into .dat file */
fprintf(ofp," f(MHz) E(deg) H(deg) R jX SWR Gain(dBi) FB(dB) SideLobes(dB)\n");
/* compute data at every frequency of interest */
for(f=min_f; f<=max_f; f+=step_f)
{
normalised_f=f/design_f;
fread((char *) ¤t[1], sizeof(struct FCOMPLEX),elements, ifp);
z_input(voltage[1], current[1], &input_impedance);
/* Compute magnitude and phase of reflection coefficient */
reflection_coefficient(input_impedance, &magnitude, &phase);
/* Compute VSWR from magnitude of reflection coefficient */
vswr=calculate_vswr(magnitude);
/* Calculate power input to antenna */
pin=calculate_power_input(input_impedance.r,current[1]); /* in Watts */
if(pin < 0.0)
{
fprintf(stderr,"input power less than 0! Probably due to self or mutual impedance being inaccurate when current not sinusidal\n");
fprintf(stderr,"f=%lf MHz Zin=%lf +i%lf\n",f/1e6, input_impedance.r, input_impedance.i);
}
/* compute gain at theta=90, phi=0 (forward direction) */
gain(90, 0, pin, normalised_f, coordinates, current, elements, &gain_E_plane, &gain_H_plane, f, design_f );
/* compute gain at theta -90 degrees (ie back - direction) */
gain(270, 0, pin, normalised_f, coordinates, current, elements, &gain_E_plane_back, &gain_H_plane_back, f, design_f);
fb_ratio=gain_E_plane-gain_E_plane_back; /* in dB, so subtract */
/* If the values of impedance are too large, the cant be printed in
the .dat file. Hence we truncate them. At this point, the numbers
are so large, that we are not likely to be able to use them anyway. */
if(input_impedance.r > 9999999)
input_impedance.r = 9999999;
if(input_impedance.i > 9999999)
input_impedance.i = 9999999;
if(input_impedance.r < -9999999)
input_impedance.r = -9999999;
if(input_impedance.i < -9999999)
input_impedance.i = -9999999;
/* Find the most importent bits of the pattern info */
/* Estimiate 3dB bandwidth using .See '-E' and '-H' options */
peak_gain=gain_E_plane;
if(flag.hflg || elements==1)
pattern_shape.three_dB_H=0.0;
else
pattern_shape.three_dB_H=(double) zbrent(error_3dB_H, 0.0,H_max,0.1);
if(flag.eflg)
pattern_shape.three_dB_E=0.0;
else
pattern_shape.three_dB_E=(double) zbrent(error_3dB_E, 90.0,E_max,0.1);
if(flag.cflg==1)
{
max_SL=find_max_sidelobe_slow(peak_gain, pin,coordinates,current,elements,f,design_f);
}
else
max_SL=0.0;
fprintf(ofp,"%9.3lf %3.1lf %3.1lf %6.2lf %6.2lf %6.3lf %10.3lf %10.3lf %10.3lf\n",f/1e6,2*(pattern_shape.three_dB_E-90), 2*pattern_shape.three_dB_H,input_impedance.r, input_impedance.i, vswr, peak_gain, fb_ratio,max_SL);
write_gain_at_various_angles(gain_fp, angular_step, pin, normalised_f, f, coordinates, current, elements, design_f);
if((min_f < max_f) && !flag.sflg)
printf("%s compleated %5.1lf%%\n",argv[0],100*(f-min_f)/(max_f-min_f));
}
/* free strings not already freed */
free_string(input_filename,0L,100L);
free_string(temp,0L,100L);
/* free vectors */
free_FCOMPLEXvector(voltage,1L,(long) elements);
free_FCOMPLEXvector(current,1L,(long) elements);
fclose(ifp);
fclose(gain_fp);
}
double error_3dB_E(double x)
{
double ans;
gain(x, 0, pin, normalised_f, coordinates, current, elements, &gain_E_plane, &gain_H_plane, f, design_f );
ans=peak_gain-gain_E_plane-3.01;
return(ans);
}
double error_3dB_H(double x)
{
double ans;
gain(0, x, pin, normalised_f, coordinates, current, elements, &gain_E_plane, &gain_H_plane, f, design_f );
ans=peak_gain-gain_H_plane-3.01;
return(ans);
}